const nTubeLocale = {
    Locales: {
        "EN": {
            "ntube.lang.related_video_holder": "Related.",
            "ntube.lang.video_title_holder": "Loading.",
            "ntube.lang.play_button": "Play/Pause.",
            "ntube.lang.pip_button": "Picture in Picture.",
            "ntube.lang.fs_button": "Fullscreen.",
            "ntube.lang.s_button": "Settings.",
            "ntube.lang.ready_action": "Ready for action.",
            "ntube.lang.experimental_ui_warning": "This UI is experimental and subject to change.",
            "ntube.lang.redirect_string": "is now redirecting...",
            "ntube.lang.redirect_to_string": "Redirecting to",
            "ntube.lang.redirect_wait_string": "This will only be a moment.",
            "ntube.errors.generic": "Failed to extract video.",
            "ntube.errors.blocked_country": "nTube failed to extract this video as it is blocked in your country.",
            "ntube.lang.storage_support_missing": "Storage missing.",
            "ntube.lang.storage_support_missing_text": "nTube requires a form of storage in order to store settings.",
        },
        "PL": {
            "ntube.lang.redirect_string": "teraz przekierowuje...",
            "ntube.lang.experimental_ui_warning": "Ten interfejs jest eksperymentalny i może się zmienić.",
            "ntube.lang.related_video_holder": "Podobne.",
            "ntube.lang.video_title_holder": "Ładuje.",
            "ntube.lang.redirect_to_string": "Przekierowuje do",
            "ntube.lang.redirect_wait_string": "To zajmie tylko chwilę.",
        }
    },
    PromisePriority: {
        BACKGROUND_TASK: 0, // default
        VISIBLE_TASK: 1, // default by postTask()
        BLOCKING_TASK: 2,
    },
    run_task: function(func, promisePriority) {
        if (!Number.isInteger(promisePriority)) throw new Error("run_task: Illegal priority: " + promisePriority);
        if (promisePriority < 0 || promisePriority > 2) throw new Error("run_task: Illegal promise priority!");
        try {
            if (window.scheduler && window.scheduler.postTask) {
                var pri = null;
                if (promisePriority === 0) {
                    pri = "background";
                }else if (promisePriority === 1) {
                    pri = "user-visible";
                }else if (promisePriority === 2) {
                    pri = "user-blocking";
                }
                if (pri === null) throw new Error("run_task: Failed to convert task priority!");
                return window.scheduler.postTask(func, {priority: pri}).result;
            }else if (window.Promise) {
                if (typeof PromiseQueuePlus !== "undefined" && window.promise_queue) {
                    if (promisePriority >= 1) return window.promise_queue.push(func);
                    return window.promise_queue.unshift(func);
                }else {
                    return new window.Promise(func);
                }
            }else {
                return ((function() {
                    var n = func();
                    return {
                        value: n,
                        then: function(y) {
                            y(n);
                        }
                    }
                })());
            }
        }catch (e) {
            console.error(e);
        }
    },
    run_promise: function(func) {
        this.run_task(func, nTube.PromisePriority.BACKGROUND_TASK);
    },
    _getNavigatorLanguage: function() {
        if (navigator.languages && navigator.languages.length) {
            return navigator.languages[0];
        } else {
            return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
        }
    },
    getNavigatorLanguage: function() {
        const o = this._getNavigatorLanguage().toUpperCase();
        if (o === "EN-GB" || o === "EN-US") return "EN";
        if (!this.Locales[o]) {
            console.warn("[lang.js] Unsupported locale: " + o);
            return "EN";
        }
        return o;
    },
    init: function() {
        const systemLocale = nTubeLocale.getNavigatorLanguage(); //TODO: Auto detection and settings.
        console.debug("[lang.js] System locale: " + systemLocale)
        var strings = document.getElementsByClassName("nlang-string");
        var titles = document.getElementsByClassName("nlang-string-title");
        function __strings() {
            for (var i = 0; i < strings.length; i++) {
                const e = strings[i];
                var fallback = e.getAttribute("ntube-lang-fallback");
                var id = e.getAttribute("ntube-lang-key");
                try {
                    if (id === undefined || id === null) {
                        console.error("nLang: ID '" + id + "' is null! [fallback=" + fallback + "]");
                        if (fallback !== undefined && fallback !== null) {
                            e.innerHTML = fallback;
                        }
                        continue;
                    }else {
                        var item = nTubeLocale.Locales[systemLocale][id];
                        if (item === undefined || item === null) {
                            console.error("nLang: Failed to find key '" + id + "'. [locale=" + systemLocale + "]");
                            e.innerHTML = fallback;
                        }else {
                            e.innerHTML = item;
                        }
                    }
                }catch (e) {
                    console.error(e);
                    e.innerHTML = fallback;
                }
            }
        }
        function __titles() {
            for (var i = 0; i < titles.length; i++) {
            const e = titles[i];
            var fallback = e.getAttribute("ntube-lang-fallback");
            var id = e.getAttribute("ntube-lang-key");
            try {
                if (id === undefined || id === null) {
                    console.error("nLang: ID '" + id + "' is null! [fallback=" + fallback + "]");
                    if (fallback !== undefined && fallback !== null) {
                        e.title = fallback;
                    }
                    continue;
                }else {
                    var item = nTubeLocale.Locales[systemLocale][id];
                    if (item === undefined || item === null) {
                        console.error("nLang: Failed to find key '" + id + "'. [locale=" + systemLocale + "]");
                        e.title = fallback;
                    }else {
                        e.title = item;
                    }
                }
            }catch (e) {
                console.error(e);
                e.title = fallback;
            }
            }
        }
        this.run_promise(__strings);
        this.run_promise(__titles);
    }
}